1.2 Go语言的特性与简洁性

在本节中,我们将从语言简洁性、并发支持以及内存管理三个方面来进行讲解。

这三个东西基本上算是 Go 语言最为显著的特性,也是与其他语言最大的区别。

语言简洁性

  • 语法简洁明了

    Go 语言的设计强调语言的简洁性,这是一开始就制定的原则,目标就是提高开发人员的开发效率,减少后续工程维护的工作量。

    Go 语言避免了很多冗余的关键字和语法结构。比如说Go语言省略了 class 的定义,使用更加直接的 struct 以及接口来完成了面向对象编程。

    Go 语言简化了编程语法,去除了很多非必要的格式,比如去除了每一行代码结尾的分号,这其实在一定程度上可以避免很多问题。

  • 清晰的错误处理

    Go 语言采用了显示的错误处理方式,不支持传统的 try/catch 异常机制。

    Go 语言中,如果函数能够产生错误,那么都需要返回一个错误类型,这就会迫使开发者必须处理错误,从而提高代码的可靠性和可维护性。

    Go 语言中的错误处理其实存在一些争议,部分人会认为每一个调用都需要处理错误,这反而增加了开发工作量。

    笔者经过实践,我认为恰恰是这一特性,保证了 Go 语言代码在很大程度上更加健壮,通过错误处理我们的代码逻辑会更加严谨,BUG 会变得很少。

  • 代码格式统一

    对于有实际工作经验的开发者来说,我们在每个团队基本都会遇到一个问题。那就是代码风格的统一,通常团队会制定一些规范手册、开发手册。

    但是我们很少会看到关于 Go 语言的规范手册,这是因为 Go 语言本身内置了 gofmt 工具,用于格式化代码,确保所有代码都有一致的风格和格式。

    这在很大程度上消除了代码风格的争议,也使得从其他开发者的代码中学习或进行代码审查变得更加容易。

    由于 Go 语言代码的简洁性,其实总共也就那么几种写法,所以基本上通过 gofmt 就可以基本保证代码风格的统一了。

并发编程支持

  • 原生的 goroutine 支持

    Go 语言为我们提供了轻量级的线程,也就是 goroutine 协程。协程的加入让我们的并发编程变得异常简单。

    我们不需要进行创建、启动、回收的流程,我们只需要一个简单的关键字 go 就可以快速的启动协程进行并发操作。

    协程在运行的时候由 Go 的调度器进行动态管理,而不是由操作系统线程处理,这就降低了并发的复杂性及开销。

    在其他部分语言中,并发的时候就是创建线程,而创建的线程也是开销极大的,属于系统级线程,一般创建一个线程的开销就会在几百 KBMB 级别。

    Go 语言创建的协程其实并不是系统级线程,所以它的开销就被压的很低,初始创建一个协程时开销仅为 2KB,显著降低了并发的资源消耗。

  • 通道

    Go 语言中的通道是一种内置的数据结构,可以在协程之间安全地传递数据。

    通过通道,开发者可以轻松地构建复杂的并发模式,如生产者-消费者模型,而无需担心数据竞争和锁问题。

    通道的设计进一步提高了协程的可用性,同时也降低了开发难度,不用去担心协程通信的问题,协程通信在其他语言中可以说是很复杂的一个事情。

  • 内存模型

    Go 语言的内存模型为并发程序定义了清晰的规则,保证了在多线程环境下的内存安全。这减少了并发程序中常见的内存一致性错误。

    Go 语言的内存模型是一套复杂的东西,我们将在后续章节中进行讲解。

内存管理

  • 自动垃圾回收(GC)

    Go 语言实现了自动垃圾回收机制,这意味着开发者不需要手动管理内存分配和释放。

    GC 是并发执行的,并且在设计上力求减少应用程序的停顿时间,这对于需要高响应速度的应用程序尤其重要。

  • 内存逃逸分析

    Go 语言编译器的一个重要特性是内存逃逸分析,它可以决定变量应该分配在栈上还是堆上。

    这种分析有助于优化内存使用,减少 GC 压力,并提升程序性能,可以让我们在编译阶段就提前发现一些问题,提高程序的稳定性及性能。

  • 值和指针的明晰区分

    Go 语言在值和指针之间提供了明确的区分,这有助于开发者更好地理解数据是如何在应用程序中流动的,也使得内存访问更加高效。

    Go 语言中,我们不需要像其他语言一样费劲的去理解指针,可以很轻松的就进行使用,同时使用时也并不容易出错。

results matching ""

    No results matching ""